
<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      <link rel="icon" href="../../../../static/images/favicon.png">
      <meta name="generator" content="mkdocs-1.3.0, mkdocs-material-8.2.8">
    
    
      
        <title>新一代高性能 Full Connects VPN 服务 WireGuard 快速部署 - WL4G DOCS</title>
      
    
    
      <link rel="stylesheet" href="../../../../assets/stylesheets/main.644de097.min.css">
      
        
        <link rel="stylesheet" href="../../../../assets/stylesheets/palette.e6a45f82.min.css">
        
      
    
    
    
      
        
        
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
        <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
      
    
    
      <link rel="stylesheet" href="../../../../static/css/util.css">
    
    <script>__md_scope=new URL("../../../..",location),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
    
      

    
    
  </head>
  
  
    
    
      
    
    
    
    
    <body dir="ltr" data-md-color-scheme="default" data-md-color-primary="" data-md-color-accent="">
  
    
    
      <script>var palette=__md_get("__palette");if(palette&&"object"==typeof palette.color)for(var key of Object.keys(palette.color))document.body.setAttribute("data-md-color-"+key,palette.color[key])</script>
    
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#full-connects-vpn-wireguard" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
      <div data-md-component="outdated" hidden>
        <aside class="md-banner md-banner--warning">
          
        </aside>
      </div>
    
    
      

<header class="md-header" data-md-component="header">
  <nav class="md-header__inner md-grid" aria-label="Header">
    <a href="../../../.." title="WL4G DOCS" class="md-header__button md-logo" aria-label="WL4G DOCS" data-md-component="logo">
      
  <img src="../../../../static/images/mylogo.jpeg" alt="logo">

    </a>
    <label class="md-header__button md-icon" for="__drawer">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
    </label>
    <div class="md-header__title" data-md-component="header-title">
      <div class="md-header__ellipsis">
        <div class="md-header__topic">
          <span class="md-ellipsis">
            WL4G DOCS
          </span>
        </div>
        <div class="md-header__topic" data-md-component="header-topic">
          <span class="md-ellipsis">
            
              新一代高性能 Full Connects VPN 服务 WireGuard 快速部署
            
          </span>
        </div>
      </div>
    </div>
    
      <form class="md-header__option" data-md-component="palette">
        
          
          
          <input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="" data-md-color-accent=""  aria-label="Switch to dark mode"  type="radio" name="__palette" id="__palette_1">
          
            <label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 6H7c-3.31 0-6 2.69-6 6s2.69 6 6 6h10c3.31 0 6-2.69 6-6s-2.69-6-6-6zm0 10H7c-2.21 0-4-1.79-4-4s1.79-4 4-4h10c2.21 0 4 1.79 4 4s-1.79 4-4 4zM7 9c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>
            </label>
          
        
          
          
          <input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="" data-md-color-accent=""  aria-label="Switch to light mode"  type="radio" name="__palette" id="__palette_2">
          
            <label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5m0 8a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3z"/></svg>
            </label>
          
        
      </form>
    
    
      <div class="md-header__option">
        <div class="md-select">
          
          <button class="md-header__button md-icon" aria-label="Select language">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m12.87 15.07-2.54-2.51.03-.03A17.52 17.52 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04M18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12m-2.62 7 1.62-4.33L19.12 17h-3.24z"/></svg>
          </button>
          <div class="md-select__inner">
            <ul class="md-select__list">
              
                <li class="md-select__item">
                  <a href="/en/" hreflang="en" class="md-select__link">
                    English
                  </a>
                </li>
                
                <li class="md-select__item">
                  <a href="/zh/" hreflang="zh" class="md-select__link">
                    简体中文
                  </a>
                </li>
                
            </ul>
          </div>
        </div>
      </div>
    
    
      <label class="md-header__button md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
      </label>
      <div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
      <label class="md-search__icon md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
      </label>
      <nav class="md-search__options" aria-label="Search">
        
        <button type="reset" class="md-search__icon md-icon" aria-label="Clear" tabindex="-1">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
        </button>
      </nav>
      
        <div class="md-search__suggest" data-md-component="search-suggest"></div>
      
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
    
    
  </nav>
  
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
          
            
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
  <div class="md-tabs__inner md-grid">
    <ul class="md-tabs__list">
      
        
  
  


  
  
  
    <li class="md-tabs__item">
      <a href="../../../.." class="md-tabs__link">
        Getting Started
      </a>
    </li>
  

      
    </ul>
  </div>
</nav>
          
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              
              <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

  


  

<nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href="../../../.." title="WL4G DOCS" class="md-nav__button md-logo" aria-label="WL4G DOCS" data-md-component="logo">
      
  <img src="../../../../static/images/mylogo.jpeg" alt="logo">

    </a>
    WL4G DOCS
  </label>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
      

  
  
  
    
    <li class="md-nav__item md-nav__item--nested">
      
      
        <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_1" data-md-state="indeterminate" type="checkbox" id="__nav_1" checked>
      
      
      
      
        <label class="md-nav__link" for="__nav_1">
          Getting Started
          <span class="md-nav__icon md-icon"></span>
        </label>
      
      <nav class="md-nav" aria-label="Getting Started" data-md-level="1">
        <label class="md-nav__title" for="__nav_1">
          <span class="md-nav__icon md-icon"></span>
          Getting Started
        </label>
        <ul class="md-nav__list" data-md-scrollfix>
          
            
              
  
  
  
    <li class="md-nav__item">
      <a href="../../../.." class="md-nav__link">
        Introduction
      </a>
    </li>
  

            
          
            
              
  
  
  
    <li class="md-nav__item">
      <a href="../../../../ABOUT_CN/" class="md-nav__link">
        About
      </a>
    </li>
  

            
          
        </ul>
      </nav>
    </li>
  

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
          
          <div class="md-content" data-md-component="content">
            <article class="md-content__inner md-typeset">
              
                


<h1 id="full-connects-vpn-wireguard">新一代高性能 Full Connects VPN 服务 WireGuard 快速部署<a class="headerlink" href="#full-connects-vpn-wireguard" title="Permanent link">&para;</a></h1>
<ul>
<li>相关文章1：<a href="https://blogs.wl4g.com/archives/3707">使用 IPSec 异地 VPN 组网搭建过程</a></li>
</ul>
<h2 id="1">1. 简介<a class="headerlink" href="#1" title="Permanent link">&para;</a></h2>
<ul>
<li>
<p>官方源码：<a href="https://github.com/WireGuard/wireguard-linux">github.com/WireGuard/wireguard-linux</a></p>
</li>
<li>
<p>官方教程：<a href="https://www.wireguard.com/quickstart/">wireguard.com/quickstart/</a></p>
</li>
<li>
<p>What is WireGuard？</p>
<p>普通的 Linux 用户到 Linux 创建者 Linus Torvalds，每个人都对 WireGuard 很感兴趣。-- Abhishek Prakash（作者）</p>
</li>
</ul>
<p>WireGuard 是一个易于部署、高性能且安全的开源 VPN，它利用了最新的加密技术和 UDP 穿洞实现了全连接。目的是提供一种更快、更简单、更精简的通用 VPN，它可以轻松地在树莓派这类低端设备到高端服务器上部署。
像 IPsec 和 <a href="https://github.com/OpenVPN/openvpn">OpenVPN</a> 等大多数其他解决方案是几十年前开发的。安全研究人员和内核开发人员 Jason Donenfeld 意识到它们速度慢且难以正确配置和管理，这让他创建了一个新的开源 VPN 协议和解决方案，它更加快速、安全、易于部署和管理。
WireGuard 最初是为 Linux 开发的，但现在可用于 Windows、macOS、BSD、iOS 和 Android。它仍在活跃开发中。</p>
<ul>
<li><strong><em>当然他并不是完美的</em></strong>，如加密或一些高速分段数据包只适合于大型数据中心，普通用户设备并不能体现出比 IPSec，OpenVPN等更好的优势。比如有人就有着不吹捧的看法：<a href="https://icloudnative.io/posts/why-not-wireguard/">icloudnative.io/posts/why-not-wireguard/</a></li>
</ul>
<h2 id="2">2. 原理<a class="headerlink" href="#2" title="Permanent link">&para;</a></h2>
<ul>
<li>使用简单的虚拟网络设备接口实现，以下描述摘自官方: <a href="https://www.wireguard.com/#simple-network-interface">wireguard.com/#simple-network-interface</a></li>
</ul>
<p>WireGuard works by adding a network interface (or multiple), like <code>eth0</code> or <code>wlan0</code>, called <code>wg0</code> (or <code>wg1</code>, <code>wg2</code>, <code>wg3</code>, etc). This network interface can then be configured normally using <code>ifconfig(8)</code> or <code>ip-address(8)</code>, with routes for it added and removed using <code>route(8)</code> or <code>ip-route(8)</code>, and so on with all the ordinary networking utilities. The specific WireGuard aspects of the interface are configured using the <code>wg(8)</code> tool. This interface acts as a tunnel interface.</p>
<ul>
<li>
<p>WireGuard associates tunnel IP addresses with public keys and remote endpoints. When the interface sends a packet to a peer, it does the following:</p>
</li>
<li>
<p>This packet is meant for <code>192.168.30.8</code>. Which peer is that? Let me look... Okay, it's for peer ABCDEFGH. (Or if it's not for any configured peer, drop the packet.)</p>
</li>
<li>
<p>Encrypt entire IP packet using peer ABCDEFGH's public key.</p>
</li>
<li>
<p>What is the remote endpoint of peer ABCDEFGH? Let me look... Okay, the endpoint is UDP port <code>53133</code> on host <code>216.58.211.110</code>.</p>
</li>
<li>
<p>Send encrypted bytes from step 2 over the Internet to <code>216.58.211.110:53133</code> using UDP.</p>
</li>
<li>
<p>When the interface receives a packet, this happens:</p>
</li>
<li>
<p>I just got a packet from UDP port <code>7361</code> on host <code>98.139.183.24</code>. Let's decrypt it!</p>
</li>
<li>
<p>It decrypted and authenticated properly for peer LMNOPQRS. Okay, let's remember that peer LMNOPQRS's most recent Internet endpoint is <code>98.139.183.24:7361</code> using UDP.</p>
</li>
<li>
<p>Once decrypted, the plain-text packet is from <code>192.168.43.89</code>. Is peer LMNOPQRS allowed to be sending us packets as <code>192.168.43.89</code>?</p>
</li>
<li>
<p>If so, accept the packet on the interface. If not, drop it.</p>
</li>
<li>
<p>Behind the scenes there is much happening to provide proper privacy, authenticity, and perfect forward secrecy, using state-of-the-art cryptography.</p>
</li>
<li>
<p><strong><em>总结实现原理：</em></strong> 相当于先通过 DDNS 机制来发现被挡在 NAT 网关后面 LAN 网络的设备在出站数据包经过 NAT 设备的 mapping port 及公网 IP，然后对端 peer 直接发送 UDP 包到此公网 IP 及 mapping port，这样就实现了 Full Connects，并不像传统 IPSec/OpenVPN 等通过中心节点转发，从而支持大量设备高性能接入，因为数据包并不经过 Wg Server。</p>
</li>
</ul>
<h2 id="3-deploy-on-docker">3. Deploy on Docker (测试推荐)<a class="headerlink" href="#3-deploy-on-docker" title="Permanent link">&para;</a></h2>
<ul>
<li>
<p>官方 Demo : <a href="https://www.wireguard.com/quickstart/#demo-server">www.wireguard.com/quickstart/#demo-server</a></p>
</li>
<li>
<p>参见镜像: <a href="https://hub.docker.com/r/linuxserver/wireguard">hub.docker.com/r/linuxserver/wireguard</a></p>
</li>
<li>
<p>参见博文: <a href="https://cloud.tencent.com/developer/article/1893909">cloud.tencent.com/developer/article/1893909</a></p>
</li>
</ul>
<h2 id="31-wg">3.1 首先所有节点需安装 wg<a class="headerlink" href="#31-wg" title="Permanent link">&para;</a></h2>
<blockquote>
<p><strong><em>注：</em></strong> 如果是 Linux 则 kernel 5.6 就内置了 wireguard module，当 kernel &gt;= 5.6 则无需安装 wireguard module，只需安装 wireguard tools 即可。 (亲测发现如 ubuntu20.4 是 5.4 但已集成了 wireguard module 到 kernel)</p>
</blockquote>
<ul>
<li>
<p>官网安装参考(支持大多数操作系统): <a href="https://www.wireguard.com/install/">wireguard.com/install/</a></p>
</li>
<li>
<p>民间实战派安装参考: <a href="https://icloudnative.io/posts/wireguard-install/">icloudnative.io/posts/wireguard-install/</a></p>
</li>
<li>
<p>大佬的一键安装脚本: <a href="https://teddysun.com/554.html">https://teddysun.com/554.html</a></p>
</li>
</ul>
<h3 id="32-wg-server-netmaker-server">3.2 WG Server 部署 (netmaker server)<a class="headerlink" href="#32-wg-server-netmaker-server" title="Permanent link">&para;</a></h3>
<ul>
<li>为了便于后续管理，本文将部署 <a href="https://github.com/gravitl/netmaker">github.com/gravitl/netmaker</a> 来对 WireGuard 自动管理，参见: <a href="https://docs.netmaker.org/quick-start.html">https://docs.netmaker.org/quick-start.html</a>，以下示例以简化了部分配置 (如禁用 https)：</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1"></a><a href="#__codelineno-0-1"><span class="linenos" data-linenos=" 1 "></span></a><span class="c1">#wget https://cdn.jsdelivr.net/gh/gravitl/netmaker@master/compose/docker-compose.yml</span>
<a id="__codelineno-0-2" name="__codelineno-0-2"></a><a href="#__codelineno-0-2"><span class="linenos" data-linenos=" 2 "></span></a>
<a id="__codelineno-0-3" name="__codelineno-0-3"></a><a href="#__codelineno-0-3"><span class="linenos" data-linenos=" 3 "></span></a>mkdir -p /mnt/disk1/netmaker/data
<a id="__codelineno-0-4" name="__codelineno-0-4"></a><a href="#__codelineno-0-4"><span class="linenos" data-linenos=" 4 "></span></a>mkdir -p /mnt/disk1/log/netmaker/
<a id="__codelineno-0-5" name="__codelineno-0-5"></a><a href="#__codelineno-0-5"><span class="linenos" data-linenos=" 5 "></span></a>
<a id="__codelineno-0-6" name="__codelineno-0-6"></a><a href="#__codelineno-0-6"><span class="linenos" data-linenos=" 6 "></span></a>cat <span class="s">&lt;&lt;EOF&gt;docker-compose.yml</span>
<a id="__codelineno-0-7" name="__codelineno-0-7"></a><a href="#__codelineno-0-7"><span class="linenos" data-linenos=" 7 "></span></a><span class="s">version: &quot;3.4&quot;</span>
<a id="__codelineno-0-8" name="__codelineno-0-8"></a><a href="#__codelineno-0-8"><span class="linenos" data-linenos=" 8 "></span></a><span class="s">services:</span>
<a id="__codelineno-0-9" name="__codelineno-0-9"></a><a href="#__codelineno-0-9"><span class="linenos" data-linenos=" 9 "></span></a><span class="s">  netmaker:</span>
<a id="__codelineno-0-10" name="__codelineno-0-10"></a><a href="#__codelineno-0-10"><span class="linenos" data-linenos="10 "></span></a><span class="s">    container_name: netmaker</span>
<a id="__codelineno-0-11" name="__codelineno-0-11"></a><a href="#__codelineno-0-11"><span class="linenos" data-linenos="11 "></span></a><span class="s">    image: gravitl/netmaker:v0.9</span>
<a id="__codelineno-0-12" name="__codelineno-0-12"></a><a href="#__codelineno-0-12"><span class="linenos" data-linenos="12 "></span></a><span class="s">    volumes:</span>
<a id="__codelineno-0-13" name="__codelineno-0-13"></a><a href="#__codelineno-0-13"><span class="linenos" data-linenos="13 "></span></a><span class="s">      #- /etc/netclient/config:/etc/netclient/config</span>
<a id="__codelineno-0-14" name="__codelineno-0-14"></a><a href="#__codelineno-0-14"><span class="linenos" data-linenos="14 "></span></a><span class="s">      - /usr/bin/wg:/usr/bin/wg</span>
<a id="__codelineno-0-15" name="__codelineno-0-15"></a><a href="#__codelineno-0-15"><span class="linenos" data-linenos="15 "></span></a><span class="s">      - dnsconfig:/root/config/dnsconfig</span>
<a id="__codelineno-0-16" name="__codelineno-0-16"></a><a href="#__codelineno-0-16"><span class="linenos" data-linenos="16 "></span></a><span class="s">      - /mnt/disk1/netmaker/data/:/root/data</span>
<a id="__codelineno-0-17" name="__codelineno-0-17"></a><a href="#__codelineno-0-17"><span class="linenos" data-linenos="17 "></span></a><span class="s">    cap_add:</span>
<a id="__codelineno-0-18" name="__codelineno-0-18"></a><a href="#__codelineno-0-18"><span class="linenos" data-linenos="18 "></span></a><span class="s">      - NET_ADMIN</span>
<a id="__codelineno-0-19" name="__codelineno-0-19"></a><a href="#__codelineno-0-19"><span class="linenos" data-linenos="19 "></span></a><span class="s">    restart: always</span>
<a id="__codelineno-0-20" name="__codelineno-0-20"></a><a href="#__codelineno-0-20"><span class="linenos" data-linenos="20 "></span></a><span class="s">    network_mode: host # 可选推荐(如果是在podman运行, 它默认是没有host网络的, 因此要么手动创建, 要么注释掉, 即使用 bridge 网络即可, 但需注意的是若使用 bridge 网络时, 当开启 client_mode=on 时注册的本机节点为 peer 其实是容器里面的接口, 并不是宿主机, 因此外部通过虚拟网络访问这台 peer 时就只能访问到此容器, 反之, 若您没有将 netmaker 节点注册为 peer 的需求则无影响)</span>
<a id="__codelineno-0-21" name="__codelineno-0-21"></a><a href="#__codelineno-0-21"><span class="linenos" data-linenos="21 "></span></a><span class="s">    ports:</span>
<a id="__codelineno-0-22" name="__codelineno-0-22"></a><a href="#__codelineno-0-22"><span class="linenos" data-linenos="22 "></span></a><span class="s">      - &quot;9909:9909&quot;</span>
<a id="__codelineno-0-23" name="__codelineno-0-23"></a><a href="#__codelineno-0-23"><span class="linenos" data-linenos="23 "></span></a><span class="s">      - &quot;50056:50056&quot;</span>
<a id="__codelineno-0-24" name="__codelineno-0-24"></a><a href="#__codelineno-0-24"><span class="linenos" data-linenos="24 "></span></a><span class="s">      - &quot;51821-51830:51821-51830/udp&quot;</span>
<a id="__codelineno-0-25" name="__codelineno-0-25"></a><a href="#__codelineno-0-25"><span class="linenos" data-linenos="25 "></span></a><span class="s">    environment:</span>
<a id="__codelineno-0-26" name="__codelineno-0-26"></a><a href="#__codelineno-0-26"><span class="linenos" data-linenos="26 "></span></a><span class="s">      SERVER_HOST: &quot;SERVER_PUBLIC_IP&quot;</span>
<a id="__codelineno-0-27" name="__codelineno-0-27"></a><a href="#__codelineno-0-27"><span class="linenos" data-linenos="27 "></span></a><span class="s">      COREDNS_ADDR: &quot;SERVER_INTRANET_IP&quot;</span>
<a id="__codelineno-0-28" name="__codelineno-0-28"></a><a href="#__codelineno-0-28"><span class="linenos" data-linenos="28 "></span></a><span class="s">      GRPC_SSL: &quot;off&quot;</span>
<a id="__codelineno-0-29" name="__codelineno-0-29"></a><a href="#__codelineno-0-29"><span class="linenos" data-linenos="29 "></span></a><span class="s">      DNS_MODE: &quot;on&quot;</span>
<a id="__codelineno-0-30" name="__codelineno-0-30"></a><a href="#__codelineno-0-30"><span class="linenos" data-linenos="30 "></span></a><span class="s">      CLIENT_MODE: &quot;on&quot; ## 将当前 netmarker server 节点也注册为 peer 节点</span>
<a id="__codelineno-0-31" name="__codelineno-0-31"></a><a href="#__codelineno-0-31"><span class="linenos" data-linenos="31 "></span></a><span class="s">      API_PORT: &quot;9909&quot;</span>
<a id="__codelineno-0-32" name="__codelineno-0-32"></a><a href="#__codelineno-0-32"><span class="linenos" data-linenos="32 "></span></a><span class="s">      GRPC_PORT: &quot;50056&quot;</span>
<a id="__codelineno-0-33" name="__codelineno-0-33"></a><a href="#__codelineno-0-33"><span class="linenos" data-linenos="33 "></span></a><span class="s">      SERVER_GRPC_WIREGUARD: &quot;off&quot;</span>
<a id="__codelineno-0-34" name="__codelineno-0-34"></a><a href="#__codelineno-0-34"><span class="linenos" data-linenos="34 "></span></a><span class="s">      CORS_ALLOWED_ORIGIN: &quot;*&quot;</span>
<a id="__codelineno-0-35" name="__codelineno-0-35"></a><a href="#__codelineno-0-35"><span class="linenos" data-linenos="35 "></span></a><span class="s">      DATABASE: &quot;sqlite&quot;</span>
<a id="__codelineno-0-36" name="__codelineno-0-36"></a><a href="#__codelineno-0-36"><span class="linenos" data-linenos="36 "></span></a><span class="s">      VERBOSITY: 3</span>
<a id="__codelineno-0-37" name="__codelineno-0-37"></a><a href="#__codelineno-0-37"><span class="linenos" data-linenos="37 "></span></a><span class="s">  netmaker-ui:</span>
<a id="__codelineno-0-38" name="__codelineno-0-38"></a><a href="#__codelineno-0-38"><span class="linenos" data-linenos="38 "></span></a><span class="s">    container_name: netmaker-ui</span>
<a id="__codelineno-0-39" name="__codelineno-0-39"></a><a href="#__codelineno-0-39"><span class="linenos" data-linenos="39 "></span></a><span class="s">    depends_on:</span>
<a id="__codelineno-0-40" name="__codelineno-0-40"></a><a href="#__codelineno-0-40"><span class="linenos" data-linenos="40 "></span></a><span class="s">      - netmaker</span>
<a id="__codelineno-0-41" name="__codelineno-0-41"></a><a href="#__codelineno-0-41"><span class="linenos" data-linenos="41 "></span></a><span class="s">    image: gravitl/netmaker-ui:v0.9</span>
<a id="__codelineno-0-42" name="__codelineno-0-42"></a><a href="#__codelineno-0-42"><span class="linenos" data-linenos="42 "></span></a><span class="s">    links:</span>
<a id="__codelineno-0-43" name="__codelineno-0-43"></a><a href="#__codelineno-0-43"><span class="linenos" data-linenos="43 "></span></a><span class="s">      - &quot;netmaker:api&quot;</span>
<a id="__codelineno-0-44" name="__codelineno-0-44"></a><a href="#__codelineno-0-44"><span class="linenos" data-linenos="44 "></span></a><span class="s">    ports:</span>
<a id="__codelineno-0-45" name="__codelineno-0-45"></a><a href="#__codelineno-0-45"><span class="linenos" data-linenos="45 "></span></a><span class="s">      - &quot;30800:80&quot;</span>
<a id="__codelineno-0-46" name="__codelineno-0-46"></a><a href="#__codelineno-0-46"><span class="linenos" data-linenos="46 "></span></a><span class="s">    environment:</span>
<a id="__codelineno-0-47" name="__codelineno-0-47"></a><a href="#__codelineno-0-47"><span class="linenos" data-linenos="47 "></span></a><span class="s">      BACKEND_URL: &quot;http://SERVER_PUBLIC_IP:9909&quot;</span>
<a id="__codelineno-0-48" name="__codelineno-0-48"></a><a href="#__codelineno-0-48"><span class="linenos" data-linenos="48 "></span></a><span class="s">    restart: always</span>
<a id="__codelineno-0-49" name="__codelineno-0-49"></a><a href="#__codelineno-0-49"><span class="linenos" data-linenos="49 "></span></a><span class="s">    # network_mode: host</span>
<a id="__codelineno-0-50" name="__codelineno-0-50"></a><a href="#__codelineno-0-50"><span class="linenos" data-linenos="50 "></span></a><span class="s">  coredns:</span>
<a id="__codelineno-0-51" name="__codelineno-0-51"></a><a href="#__codelineno-0-51"><span class="linenos" data-linenos="51 "></span></a><span class="s">    depends_on:</span>
<a id="__codelineno-0-52" name="__codelineno-0-52"></a><a href="#__codelineno-0-52"><span class="linenos" data-linenos="52 "></span></a><span class="s">      - netmaker</span>
<a id="__codelineno-0-53" name="__codelineno-0-53"></a><a href="#__codelineno-0-53"><span class="linenos" data-linenos="53 "></span></a><span class="s">    image: coredns/coredns</span>
<a id="__codelineno-0-54" name="__codelineno-0-54"></a><a href="#__codelineno-0-54"><span class="linenos" data-linenos="54 "></span></a><span class="s">    command: -conf /root/dnsconfig/Corefile</span>
<a id="__codelineno-0-55" name="__codelineno-0-55"></a><a href="#__codelineno-0-55"><span class="linenos" data-linenos="55 "></span></a><span class="s">    container_name: coredns</span>
<a id="__codelineno-0-56" name="__codelineno-0-56"></a><a href="#__codelineno-0-56"><span class="linenos" data-linenos="56 "></span></a><span class="s">    restart: always</span>
<a id="__codelineno-0-57" name="__codelineno-0-57"></a><a href="#__codelineno-0-57"><span class="linenos" data-linenos="57 "></span></a><span class="s">    network_mode: host</span>
<a id="__codelineno-0-58" name="__codelineno-0-58"></a><a href="#__codelineno-0-58"><span class="linenos" data-linenos="58 "></span></a><span class="s">    volumes:</span>
<a id="__codelineno-0-59" name="__codelineno-0-59"></a><a href="#__codelineno-0-59"><span class="linenos" data-linenos="59 "></span></a><span class="s">      - dnsconfig:/root/dnsconfig</span>
<a id="__codelineno-0-60" name="__codelineno-0-60"></a><a href="#__codelineno-0-60"><span class="linenos" data-linenos="60 "></span></a><span class="s">volumes:</span>
<a id="__codelineno-0-61" name="__codelineno-0-61"></a><a href="#__codelineno-0-61"><span class="linenos" data-linenos="61 "></span></a><span class="s">  dnsconfig: {}</span>
<a id="__codelineno-0-62" name="__codelineno-0-62"></a><a href="#__codelineno-0-62"><span class="linenos" data-linenos="62 "></span></a><span class="s">EOF</span>
<a id="__codelineno-0-63" name="__codelineno-0-63"></a><a href="#__codelineno-0-63"><span class="linenos" data-linenos="63 "></span></a>
<a id="__codelineno-0-64" name="__codelineno-0-64"></a><a href="#__codelineno-0-64"><span class="linenos" data-linenos="64 "></span></a><span class="c1"># 替换为您的实际值</span>
<a id="__codelineno-0-65" name="__codelineno-0-65"></a><a href="#__codelineno-0-65"><span class="linenos" data-linenos="65 "></span></a><span class="nb">export</span> <span class="nv">publicIp</span><span class="o">=</span><span class="s1">&#39;your server public ip&#39;</span>
<a id="__codelineno-0-66" name="__codelineno-0-66"></a><a href="#__codelineno-0-66"><span class="linenos" data-linenos="66 "></span></a><span class="nb">export</span> <span class="nv">intranetIp</span><span class="o">=</span><span class="k">$(</span>ip route get <span class="m">1</span> <span class="p">|</span> sed -n <span class="s1">&#39;s/^.*src \([0-9.]*\) .*$/\1/p&#39;</span><span class="k">)</span>
<a id="__codelineno-0-67" name="__codelineno-0-67"></a><a href="#__codelineno-0-67"><span class="linenos" data-linenos="67 "></span></a><span class="c1">#export topDomain=&#39;your server top domain&#39;</span>
<a id="__codelineno-0-68" name="__codelineno-0-68"></a><a href="#__codelineno-0-68"><span class="linenos" data-linenos="68 "></span></a><span class="nb">export</span> <span class="nv">masterKey</span><span class="o">=</span><span class="k">$(</span>tr -dc A-Za-z0-9 &lt;/dev/urandom <span class="p">|</span> head -c <span class="m">30</span> <span class="p">;</span> <span class="nb">echo</span> <span class="s1">&#39;&#39;</span><span class="k">)</span>
<a id="__codelineno-0-69" name="__codelineno-0-69"></a><a href="#__codelineno-0-69"><span class="linenos" data-linenos="69 "></span></a>
<a id="__codelineno-0-70" name="__codelineno-0-70"></a><a href="#__codelineno-0-70"><span class="linenos" data-linenos="70 "></span></a>sed -i <span class="s2">&quot;s/SERVER_PUBLIC_IP/</span><span class="nv">$publicIp</span><span class="s2">/g&quot;</span> docker-compose.yml
<a id="__codelineno-0-71" name="__codelineno-0-71"></a><a href="#__codelineno-0-71"><span class="linenos" data-linenos="71 "></span></a>sed -i <span class="s2">&quot;s/SERVER_INTRANET_IP/</span><span class="nv">$intranetIp</span><span class="s2">/g&quot;</span> docker-compose.yml
<a id="__codelineno-0-72" name="__codelineno-0-72"></a><a href="#__codelineno-0-72"><span class="linenos" data-linenos="72 "></span></a><span class="c1">#sed -i &quot;s/NETMAKER_BASE_DOMAIN/$topDomain/g&quot; docker-compose.yml</span>
<a id="__codelineno-0-73" name="__codelineno-0-73"></a><a href="#__codelineno-0-73"><span class="linenos" data-linenos="73 "></span></a><span class="c1">#sed -i &quot;s/REPLACE_MASTER_KEY/$masterKey/g&quot; docker-compose.yml</span>
<a id="__codelineno-0-74" name="__codelineno-0-74"></a><a href="#__codelineno-0-74"><span class="linenos" data-linenos="74 "></span></a>
<a id="__codelineno-0-75" name="__codelineno-0-75"></a><a href="#__codelineno-0-75"><span class="linenos" data-linenos="75 "></span></a><span class="c1">## 若容器引擎是 docker</span>
<a id="__codelineno-0-76" name="__codelineno-0-76"></a><a href="#__codelineno-0-76"><span class="linenos" data-linenos="76 "></span></a>docker-compose up -d
<a id="__codelineno-0-77" name="__codelineno-0-77"></a><a href="#__codelineno-0-77"><span class="linenos" data-linenos="77 "></span></a>
<a id="__codelineno-0-78" name="__codelineno-0-78"></a><a href="#__codelineno-0-78"><span class="linenos" data-linenos="78 "></span></a><span class="c1">## 若容器引擎是 containerd</span>
<a id="__codelineno-0-79" name="__codelineno-0-79"></a><a href="#__codelineno-0-79"><span class="linenos" data-linenos="79 "></span></a>nerdctl compose -f docker-compose.yml up
<a id="__codelineno-0-80" name="__codelineno-0-80"></a><a href="#__codelineno-0-80"><span class="linenos" data-linenos="80 "></span></a>
<a id="__codelineno-0-81" name="__codelineno-0-81"></a><a href="#__codelineno-0-81"><span class="linenos" data-linenos="81 "></span></a><span class="c1">## 若容器引擎是 podman</span>
<a id="__codelineno-0-82" name="__codelineno-0-82"></a><a href="#__codelineno-0-82"><span class="linenos" data-linenos="82 "></span></a><span class="c1">#pip3 install podman-compose</span>
<a id="__codelineno-0-83" name="__codelineno-0-83"></a><a href="#__codelineno-0-83"><span class="linenos" data-linenos="83 "></span></a>podman-compose up --force-recreate -d
</code></pre></div>
<ul>
<li>
<p><strong><em>注：</em></strong> 其中 <code>network_mode: host</code> 为可选，如果是在podman运行, 它默认是没有 <code>host</code> 网络的, 因此要么手动创建, 要么注释掉, 即使用 <code>bridge</code> 网络即可, 但需注意的是若使用 bridge 网络时，当开启 client_mode=on 时注册的本机节点为 peer 其实是容器里面的接口，并不是宿主机, 因此外部通过虚拟网络访问这台 peer 时就只能访问到此容器，反之若您没有将 netmaker 节点注册为 peer 的需求则无影响。</p>
</li>
<li>
<p>然后访问 netmaker 控制台：<code>http://&lt;SERVER_PUBLIC_IP&gt;:30800/</code> ， 如果是云主机，请确保已放开安全组规则，<code>30800,9909/tcp</code>(控制台前后端 dashboard/netmaker api port), <code>50056/tcp</code>(如netclient join时会请求grpc port), <code>51821-51830/udp</code>(之后接收 peers 心跳续约 udp 端口)</p>
</li>
<li>
<p>更全面配置参见官方文档: <a href="https://docs.netmaker.org/quick-start.html">docs.netmaker.org/quick-start.html</a></p>
</li>
</ul>
<h3 id="33-wg-peer-client">3.3 WG Peer Client 部署<a class="headerlink" href="#33-wg-peer-client" title="Permanent link">&para;</a></h3>
<ul>
<li>这里使用 netclient 来简化 wg 配置</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1"></a><a href="#__codelineno-1-1"><span class="linenos" data-linenos=" 1 "></span></a><span class="c1">## 注意版本与 netmaker server 对应，否则可能有问题</span>
<a id="__codelineno-1-2" name="__codelineno-1-2"></a><a href="#__codelineno-1-2"><span class="linenos" data-linenos=" 2 "></span></a>&gt; curl -OL <span class="s1">&#39;https://github.com/gravitl/netmaker/releases/download/v0.9.0/netclient&#39;</span>
<a id="__codelineno-1-3" name="__codelineno-1-3"></a><a href="#__codelineno-1-3"><span class="linenos" data-linenos=" 3 "></span></a>
<a id="__codelineno-1-4" name="__codelineno-1-4"></a><a href="#__codelineno-1-4"><span class="linenos" data-linenos=" 4 "></span></a><span class="c1">## 再在 netmaker dashboard 配置好网络及 AssessKey，根据提示复制 join 命令，如：</span>
<a id="__codelineno-1-5" name="__codelineno-1-5"></a><a href="#__codelineno-1-5"><span class="linenos" data-linenos=" 5 "></span></a><span class="c1"># &gt; sudo ./netclient join -t eyJhcGljb25uc3RyaWxxxxxxxxxxxx</span>
<a id="__codelineno-1-6" name="__codelineno-1-6"></a><a href="#__codelineno-1-6"><span class="linenos" data-linenos=" 6 "></span></a><span class="m">2022</span>/06/18 <span class="m">12</span>:45:24 <span class="o">[</span>netclient<span class="o">]</span> joining office-vpn at <span class="m">118</span>.31.64.80:50056
<a id="__codelineno-1-7" name="__codelineno-1-7"></a><a href="#__codelineno-1-7"><span class="linenos" data-linenos=" 7 "></span></a><span class="m">2022</span>/06/18 <span class="m">12</span>:45:24 <span class="o">[</span>netclient<span class="o">]</span> node created on remote server...updating configs
<a id="__codelineno-1-8" name="__codelineno-1-8"></a><a href="#__codelineno-1-8"><span class="linenos" data-linenos=" 8 "></span></a><span class="m">2022</span>/06/18 <span class="m">12</span>:45:24 <span class="o">[</span>netclient<span class="o">]</span> retrieving peers
<a id="__codelineno-1-9" name="__codelineno-1-9"></a><a href="#__codelineno-1-9"><span class="linenos" data-linenos=" 9 "></span></a><span class="m">2022</span>/06/18 <span class="m">12</span>:45:24 <span class="o">[</span>netclient<span class="o">]</span> starting wireguard
<a id="__codelineno-1-10" name="__codelineno-1-10"></a><a href="#__codelineno-1-10"><span class="linenos" data-linenos="10 "></span></a><span class="m">2022</span>/06/18 <span class="m">12</span>:45:25 <span class="o">[</span>netclient<span class="o">]</span> joined my-office-vpn
</code></pre></div>
<ul>
<li>查看 wg peers 连接状态</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1"></a><a href="#__codelineno-2-1"><span class="linenos" data-linenos=" 1 "></span></a>&gt; sudo wg show
<a id="__codelineno-2-2" name="__codelineno-2-2"></a><a href="#__codelineno-2-2"><span class="linenos" data-linenos=" 2 "></span></a>interface: nm-my-vpn
<a id="__codelineno-2-3" name="__codelineno-2-3"></a><a href="#__codelineno-2-3"><span class="linenos" data-linenos=" 3 "></span></a>  public key: <span class="nv">VlccxyMYNkRV6jKFH6NFPQSK1UHfVrWdr6JX79AIgXA</span><span class="o">=</span>
<a id="__codelineno-2-4" name="__codelineno-2-4"></a><a href="#__codelineno-2-4"><span class="linenos" data-linenos=" 4 "></span></a>  private key: <span class="o">(</span>hidden<span class="o">)</span>
<a id="__codelineno-2-5" name="__codelineno-2-5"></a><a href="#__codelineno-2-5"><span class="linenos" data-linenos=" 5 "></span></a>  listening port: <span class="m">56849</span>
<a id="__codelineno-2-6" name="__codelineno-2-6"></a><a href="#__codelineno-2-6"><span class="linenos" data-linenos=" 6 "></span></a>
<a id="__codelineno-2-7" name="__codelineno-2-7"></a><a href="#__codelineno-2-7"><span class="linenos" data-linenos=" 7 "></span></a>peer: 18Ly39cptMQKgrBONMJ6zHh7516oLOqxxxxxxxxx
<a id="__codelineno-2-8" name="__codelineno-2-8"></a><a href="#__codelineno-2-8"><span class="linenos" data-linenos=" 8 "></span></a>  endpoint: <span class="m">118</span>.xx.xx.xx:51821
<a id="__codelineno-2-9" name="__codelineno-2-9"></a><a href="#__codelineno-2-9"><span class="linenos" data-linenos=" 9 "></span></a>  allowed ips: <span class="m">192</span>.168.8.1/32
<a id="__codelineno-2-10" name="__codelineno-2-10"></a><a href="#__codelineno-2-10"><span class="linenos" data-linenos="10 "></span></a>  latest handshake: <span class="m">14</span> seconds ago
<a id="__codelineno-2-11" name="__codelineno-2-11"></a><a href="#__codelineno-2-11"><span class="linenos" data-linenos="11 "></span></a>  transfer: <span class="m">3</span>.79 KiB received, <span class="m">1</span>.25 KiB sent
<a id="__codelineno-2-12" name="__codelineno-2-12"></a><a href="#__codelineno-2-12"><span class="linenos" data-linenos="12 "></span></a>  persistent keepalive: every <span class="m">20</span> seconds
<a id="__codelineno-2-13" name="__codelineno-2-13"></a><a href="#__codelineno-2-13"><span class="linenos" data-linenos="13 "></span></a>
<a id="__codelineno-2-14" name="__codelineno-2-14"></a><a href="#__codelineno-2-14"><span class="linenos" data-linenos="14 "></span></a>peer: YZpCjADSAtauFmPhxGySpkF5Gxk4/Exxxxxxx
<a id="__codelineno-2-15" name="__codelineno-2-15"></a><a href="#__codelineno-2-15"><span class="linenos" data-linenos="15 "></span></a>  endpoint: <span class="m">120</span>.xx.xx.xx:40216
<a id="__codelineno-2-16" name="__codelineno-2-16"></a><a href="#__codelineno-2-16"><span class="linenos" data-linenos="16 "></span></a>  allowed ips: <span class="m">192</span>.168.8.2/32
<a id="__codelineno-2-17" name="__codelineno-2-17"></a><a href="#__codelineno-2-17"><span class="linenos" data-linenos="17 "></span></a>  latest handshake: <span class="m">2</span> minutes, <span class="m">13</span> seconds ago
<a id="__codelineno-2-18" name="__codelineno-2-18"></a><a href="#__codelineno-2-18"><span class="linenos" data-linenos="18 "></span></a>  transfer: <span class="m">6</span>.50 KiB received, <span class="m">3</span>.92 KiB sent
<a id="__codelineno-2-19" name="__codelineno-2-19"></a><a href="#__codelineno-2-19"><span class="linenos" data-linenos="19 "></span></a>  persistent keepalive: every <span class="m">20</span> seconds
</code></pre></div>
<ul>
<li>查看 wg peers 配置（可拷贝到 TunSafe / Wireguard Client Win 等客户端进行配置）</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1"></a><a href="#__codelineno-3-1"><span class="linenos" data-linenos=" 1 "></span></a>&gt; sudo wg showconf nm-my-vpn
<a id="__codelineno-3-2" name="__codelineno-3-2"></a><a href="#__codelineno-3-2"><span class="linenos" data-linenos=" 2 "></span></a>
<a id="__codelineno-3-3" name="__codelineno-3-3"></a><a href="#__codelineno-3-3"><span class="linenos" data-linenos=" 3 "></span></a><span class="o">[</span>Interface<span class="o">]</span>
<a id="__codelineno-3-4" name="__codelineno-3-4"></a><a href="#__codelineno-3-4"><span class="linenos" data-linenos=" 4 "></span></a><span class="nv">ListenPort</span> <span class="o">=</span> <span class="m">33623</span>
<a id="__codelineno-3-5" name="__codelineno-3-5"></a><a href="#__codelineno-3-5"><span class="linenos" data-linenos=" 5 "></span></a><span class="nv">PrivateKey</span> <span class="o">=</span> <span class="nv">0Pl6x0r3NtfGIglISiN3XFlyV7rcRaek28OyzYDeaHo</span><span class="o">=</span>
<a id="__codelineno-3-6" name="__codelineno-3-6"></a><a href="#__codelineno-3-6"><span class="linenos" data-linenos=" 6 "></span></a>
<a id="__codelineno-3-7" name="__codelineno-3-7"></a><a href="#__codelineno-3-7"><span class="linenos" data-linenos=" 7 "></span></a><span class="o">[</span>Peer<span class="o">]</span>
<a id="__codelineno-3-8" name="__codelineno-3-8"></a><a href="#__codelineno-3-8"><span class="linenos" data-linenos=" 8 "></span></a><span class="nv">PublicKey</span> <span class="o">=</span> <span class="nv">LVvCZ4FGPPtTjAqdzhThgGhc4DUmIGSwVe7UR8VxukU</span><span class="o">=</span>
<a id="__codelineno-3-9" name="__codelineno-3-9"></a><a href="#__codelineno-3-9"><span class="linenos" data-linenos=" 9 "></span></a><span class="nv">AllowedIPs</span> <span class="o">=</span> <span class="m">192</span>.168.8.1/32
<a id="__codelineno-3-10" name="__codelineno-3-10"></a><a href="#__codelineno-3-10"><span class="linenos" data-linenos="10 "></span></a><span class="nv">Endpoint</span> <span class="o">=</span> <span class="m">118</span>.xx.xx.xx:51821
<a id="__codelineno-3-11" name="__codelineno-3-11"></a><a href="#__codelineno-3-11"><span class="linenos" data-linenos="11 "></span></a><span class="nv">PersistentKeepalive</span> <span class="o">=</span> <span class="m">20</span>
<a id="__codelineno-3-12" name="__codelineno-3-12"></a><a href="#__codelineno-3-12"><span class="linenos" data-linenos="12 "></span></a>
<a id="__codelineno-3-13" name="__codelineno-3-13"></a><a href="#__codelineno-3-13"><span class="linenos" data-linenos="13 "></span></a><span class="o">[</span>Peer<span class="o">]</span>
<a id="__codelineno-3-14" name="__codelineno-3-14"></a><a href="#__codelineno-3-14"><span class="linenos" data-linenos="14 "></span></a><span class="nv">PublicKey</span> <span class="o">=</span> LVqimk87yJwZsu/7dle7rChj9rN1DHMNvluJSwkQeH8<span class="o">=</span>
<a id="__codelineno-3-15" name="__codelineno-3-15"></a><a href="#__codelineno-3-15"><span class="linenos" data-linenos="15 "></span></a><span class="nv">AllowedIPs</span> <span class="o">=</span> <span class="m">192</span>.168.8.2/32
<a id="__codelineno-3-16" name="__codelineno-3-16"></a><a href="#__codelineno-3-16"><span class="linenos" data-linenos="16 "></span></a><span class="nv">Endpoint</span> <span class="o">=</span> <span class="m">120</span>.xx.xx.xx:40216
<a id="__codelineno-3-17" name="__codelineno-3-17"></a><a href="#__codelineno-3-17"><span class="linenos" data-linenos="17 "></span></a><span class="nv">PersistentKeepalive</span> <span class="o">=</span> <span class="m">20</span>
</code></pre></div>
<ul>
<li>查看本地对应虚拟接口（就会看到一个叫 nm-my-vpn 的虚拟接口，即在 netmaker dashboard 上创建的网络名称）</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1"></a><a href="#__codelineno-4-1"><span class="linenos" data-linenos="1 "></span></a>&gt; ip a
<a id="__codelineno-4-2" name="__codelineno-4-2"></a><a href="#__codelineno-4-2"><span class="linenos" data-linenos="2 "></span></a>...
<a id="__codelineno-4-3" name="__codelineno-4-3"></a><a href="#__codelineno-4-3"><span class="linenos" data-linenos="3 "></span></a><span class="m">32</span>: nm-my-vpn: &lt;POINTOPOINT,NOARP,UP,LOWER_UP&gt; mtu <span class="m">1280</span> qdisc noqueue state UNKNOWN group default qlen <span class="m">1000</span>
<a id="__codelineno-4-4" name="__codelineno-4-4"></a><a href="#__codelineno-4-4"><span class="linenos" data-linenos="4 "></span></a>    link/none 
<a id="__codelineno-4-5" name="__codelineno-4-5"></a><a href="#__codelineno-4-5"><span class="linenos" data-linenos="5 "></span></a>    inet <span class="m">192</span>.168.8.3/24 scope global nm-my-vpn  <span class="c1"># 本机分配的是 192.168.8.3</span>
<a id="__codelineno-4-6" name="__codelineno-4-6"></a><a href="#__codelineno-4-6"><span class="linenos" data-linenos="6 "></span></a>       valid_lft forever preferred_lft forever
</code></pre></div>
<ul>
<li>验证虚拟网络</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1"></a><a href="#__codelineno-5-1"><span class="linenos" data-linenos="1 "></span></a><span class="c1"># 在一端内网的 peerA 机器，启动测试服务</span>
<a id="__codelineno-5-2" name="__codelineno-5-2"></a><a href="#__codelineno-5-2"><span class="linenos" data-linenos="2 "></span></a>&gt; python3 -m http.server
<a id="__codelineno-5-3" name="__codelineno-5-3"></a><a href="#__codelineno-5-3"><span class="linenos" data-linenos="3 "></span></a>
<a id="__codelineno-5-4" name="__codelineno-5-4"></a><a href="#__codelineno-5-4"><span class="linenos" data-linenos="4 "></span></a><span class="c1"># 然后在另一端内网的 peerB 机器请求此服务（其中 peerA 和 peerB 分别为相隔十万八千里的两个内网机器）</span>
<a id="__codelineno-5-5" name="__codelineno-5-5"></a><a href="#__codelineno-5-5"><span class="linenos" data-linenos="5 "></span></a>&gt; curl -v <span class="m">192</span>.168.8.2:8000  <span class="c1"># 对应 UDP 的打洞: 120.xx.xx.xx:40216 公网地址</span>
</code></pre></div>
<ul>
<li>
<p>其实上面 <code>netclient</code> 原理就等价于几条设置虚拟接口的命令，具体可以从 WireGuard 官网给出的 demo 脚本中看出: <a href="https://www.wireguard.com/quickstart/">wireguard.com/quickstart/</a> 所: <a href="https://git.zx2c4.com/wireguard-tools/plain/contrib/ncat-client-server/client.sh">git.zx2c4.com/wireguard-tools/plain/contrib/ncat-client-server/client.sh</a> ，此地址可能被墙，为方便查看直接贴出内容如下:
<div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1"></a><a href="#__codelineno-6-1"><span class="linenos" data-linenos=" 1 "></span></a><span class="ch">#!/bin/bash</span>
<a id="__codelineno-6-2" name="__codelineno-6-2"></a><a href="#__codelineno-6-2"><span class="linenos" data-linenos=" 2 "></span></a><span class="nb">set</span> -ex
<a id="__codelineno-6-3" name="__codelineno-6-3"></a><a href="#__codelineno-6-3"><span class="linenos" data-linenos=" 3 "></span></a><span class="o">[[</span> <span class="nv">$UID</span> <span class="o">==</span> <span class="m">0</span> <span class="o">]]</span> <span class="o">||</span> <span class="o">{</span> <span class="nb">echo</span> <span class="s2">&quot;You must be root to run this.&quot;</span><span class="p">;</span> <span class="nb">exit</span> <span class="m">1</span><span class="p">;</span> <span class="o">}</span>
<a id="__codelineno-6-4" name="__codelineno-6-4"></a><a href="#__codelineno-6-4"><span class="linenos" data-linenos=" 4 "></span></a><span class="nb">exec</span> <span class="m">3</span>&lt;&gt;/dev/tcp/demo.wireguard.com/42912
<a id="__codelineno-6-5" name="__codelineno-6-5"></a><a href="#__codelineno-6-5"><span class="linenos" data-linenos=" 5 "></span></a><span class="nv">privatekey</span><span class="o">=</span><span class="s2">&quot;</span><span class="k">$(</span>wg genkey<span class="k">)</span><span class="s2">&quot;</span>  <span class="c1"># 首先使用 wg tools 生成私钥</span>
<a id="__codelineno-6-6" name="__codelineno-6-6"></a><a href="#__codelineno-6-6"><span class="linenos" data-linenos=" 6 "></span></a>wg pubkey <span class="o">&lt;&lt;&lt;</span><span class="s2">&quot;</span><span class="nv">$privatekey</span><span class="s2">&quot;</span> &gt;<span class="p">&amp;</span><span class="m">3</span> <span class="c1"># 根据私钥生成公钥</span>
<a id="__codelineno-6-7" name="__codelineno-6-7"></a><a href="#__codelineno-6-7"><span class="linenos" data-linenos=" 7 "></span></a><span class="nv">IFS</span><span class="o">=</span>: <span class="nb">read</span> -r status server_pubkey server_port internal_ip &lt;<span class="p">&amp;</span><span class="m">3</span>
<a id="__codelineno-6-8" name="__codelineno-6-8"></a><a href="#__codelineno-6-8"><span class="linenos" data-linenos=" 8 "></span></a><span class="o">[[</span> <span class="nv">$status</span> <span class="o">==</span> OK <span class="o">]]</span>
<a id="__codelineno-6-9" name="__codelineno-6-9"></a><a href="#__codelineno-6-9"><span class="linenos" data-linenos=" 9 "></span></a>ip link del dev wg0 <span class="m">2</span>&gt;/dev/null <span class="o">||</span> <span class="nb">true</span>
<a id="__codelineno-6-10" name="__codelineno-6-10"></a><a href="#__codelineno-6-10"><span class="linenos" data-linenos="10 "></span></a>ip link add dev wg0 <span class="nb">type</span> wireguard <span class="c1">## 添加虚拟网络接口 wg0</span>
<a id="__codelineno-6-11" name="__codelineno-6-11"></a><a href="#__codelineno-6-11"><span class="linenos" data-linenos="11 "></span></a>wg <span class="nb">set</span> wg0 private-key &lt;<span class="o">(</span><span class="nb">echo</span> <span class="s2">&quot;</span><span class="nv">$privatekey</span><span class="s2">&quot;</span><span class="o">)</span> peer <span class="s2">&quot;</span><span class="nv">$server_pubkey</span><span class="s2">&quot;</span> allowed-ips <span class="m">0</span>.0.0.0/0 endpoint <span class="s2">&quot;demo.wireguard.com:</span><span class="nv">$server_port</span><span class="s2">&quot;</span> persistent-keepalive <span class="m">25</span>  <span class="c1">## 配置虚拟网络接口 wg0 的密钥及 wg server 的endpoint 地址等.</span>
<a id="__codelineno-6-12" name="__codelineno-6-12"></a><a href="#__codelineno-6-12"><span class="linenos" data-linenos="12 "></span></a>ip addr add <span class="s2">&quot;</span><span class="nv">$internal_ip</span><span class="s2">&quot;</span>/24 dev wg0 <span class="c1">## 给虚拟接口 wg0 分配虚拟网段</span>
<a id="__codelineno-6-13" name="__codelineno-6-13"></a><a href="#__codelineno-6-13"><span class="linenos" data-linenos="13 "></span></a>ip link <span class="nb">set</span> up dev wg0 <span class="c1">## 启动虚拟接口 wg0</span>
<a id="__codelineno-6-14" name="__codelineno-6-14"></a><a href="#__codelineno-6-14"><span class="linenos" data-linenos="14 "></span></a><span class="k">if</span> <span class="o">[</span> <span class="s2">&quot;</span><span class="nv">$1</span><span class="s2">&quot;</span> <span class="o">==</span> <span class="s2">&quot;default-route&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
<a id="__codelineno-6-15" name="__codelineno-6-15"></a><a href="#__codelineno-6-15"><span class="linenos" data-linenos="15 "></span></a>    <span class="nv">host</span><span class="o">=</span><span class="s2">&quot;</span><span class="k">$(</span>wg show wg0 endpoints <span class="p">|</span> sed -n <span class="s1">&#39;s/.*\t\(.*\):.*/\1/p&#39;</span><span class="k">)</span><span class="s2">&quot;</span>
<a id="__codelineno-6-16" name="__codelineno-6-16"></a><a href="#__codelineno-6-16"><span class="linenos" data-linenos="16 "></span></a>    ip route add <span class="k">$(</span>ip route get <span class="nv">$host</span> <span class="p">|</span> sed <span class="s1">&#39;/ via [0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/{s/^\(.* via [0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/}&#39;</span> <span class="p">|</span> head -n <span class="m">1</span><span class="k">)</span> <span class="m">2</span>&gt;/dev/null <span class="o">||</span> <span class="nb">true</span>
<a id="__codelineno-6-17" name="__codelineno-6-17"></a><a href="#__codelineno-6-17"><span class="linenos" data-linenos="17 "></span></a>    ip route add <span class="m">0</span>/1 dev wg0 <span class="c1">## 设置路由（引导需要连接此虚拟网络的流量）</span>
<a id="__codelineno-6-18" name="__codelineno-6-18"></a><a href="#__codelineno-6-18"><span class="linenos" data-linenos="18 "></span></a>    ip route add <span class="m">128</span>/1 dev wg0
<a id="__codelineno-6-19" name="__codelineno-6-19"></a><a href="#__codelineno-6-19"><span class="linenos" data-linenos="19 "></span></a><span class="k">fi</span>
</code></pre></div></p>
</li>
<li>
<p>由官方 <a href="https://download.wireguard.com/windows-client/">download.wireguard.com/windows-client/</a> 提供的 Windows 客户端(傻瓜式安装)。</p>
</li>
<li>
<p>由 <a href="https://tunsafe.com/download">TunSafe download</a> 提供的 Windows 客户端(傻瓜式安装)。</p>
</li>
</ul>
<h2 id="4-deploy-on-kubernetes">4. Deploy on Kubernetes (生产推荐)<a class="headerlink" href="#4-deploy-on-kubernetes" title="Permanent link">&para;</a></h2>
<ul>
<li><a href="https://notes.icool.io/k3s-wiregurad/">基于Wireguard组网Kubernetes(k3s)集群搭建</a></li>
</ul>
<h2 id="5-faq">5. FAQ<a class="headerlink" href="#5-faq" title="Permanent link">&para;</a></h2>
<h3 id="51-nerdctl-run-netmaker-failed-to-create-shim-oci-runtime-create-failed-container_linuxgo380-starting-container-process-caused-process_linuxgo545-container-init-caused-running-hook-0-error-running-hook-exit-status-1-stdout-stderr-time2022-06-09t1054340800-levelfatal-msgfailed-to-call-cnisetup-plugin-typebridge-failed-add-incompatible-cni-versions-config-is-100-plugin-supports-010-020-030-031-040">5.1 使用 <code>nerdctl run</code> 启动 netmaker 容器时报错: <code>failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: Running hook #0:: error running hook: exit status 1, stdout: , stderr: time="2022-06-09T10:54:34+08:00" level=fatal msg="failed to call cni.Setup: plugin type="bridge" failed (add): incompatible CNI versions; config is "1.0.0", plugin supports ["0.1.0" "0.2.0" "0.3.0" "0.3.1" "0.4.0"]"</code><a class="headerlink" href="#51-nerdctl-run-netmaker-failed-to-create-shim-oci-runtime-create-failed-container_linuxgo380-starting-container-process-caused-process_linuxgo545-container-init-caused-running-hook-0-error-running-hook-exit-status-1-stdout-stderr-time2022-06-09t1054340800-levelfatal-msgfailed-to-call-cnisetup-plugin-typebridge-failed-add-incompatible-cni-versions-config-is-100-plugin-supports-010-020-030-031-040" title="Permanent link">&para;</a></h3>
<ul>
<li>原因是因为 cni 配置的版本不被 cni 支持，请检查: <code>cat /etc/cni/net.d/nerdctl-wireguard_default.conflist</code> 是否配置的 <code>1.0.0</code>，可尝试改为 <code>0.4.0</code></li>
</ul>
<h3 id="52-wireguard-windows">5.2 关于 WireGuard 在 Windows 上配置可能出现的错误及解决方案<a class="headerlink" href="#52-wireguard-windows" title="Permanent link">&para;</a></h3>
<ul>
<li>执行 netclient.exe 时可能碰到的错误（注：应该在 PowerShell 中执行，否则在普通 cmd 运行可能报错找不到 wg.exe）</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1"></a><a href="#__codelineno-7-1"><span class="linenos" data-linenos=" 1 "></span></a>D:\download&gt; .\netclient.exe join -t xxxxxxxxxxxx
<a id="__codelineno-7-2" name="__codelineno-7-2"></a><a href="#__codelineno-7-2"><span class="linenos" data-linenos=" 2 "></span></a>2022/06/19 14:30:40 Gravitl Netclient on Windows started
<a id="__codelineno-7-3" name="__codelineno-7-3"></a><a href="#__codelineno-7-3"><span class="linenos" data-linenos=" 3 "></span></a>2022/06/19 14:30:40 [netclient] joining sc-devvpn at 120.xx.xx.xx:50056
<a id="__codelineno-7-4" name="__codelineno-7-4"></a><a href="#__codelineno-7-4"><span class="linenos" data-linenos=" 4 "></span></a>2022/06/19 14:30:41 [netclient] node created on remote server...updating configs
<a id="__codelineno-7-5" name="__codelineno-7-5"></a><a href="#__codelineno-7-5"><span class="linenos" data-linenos=" 5 "></span></a>2022/06/19 14:30:41 [netclient] retrieving peers
<a id="__codelineno-7-6" name="__codelineno-7-6"></a><a href="#__codelineno-7-6"><span class="linenos" data-linenos=" 6 "></span></a>2022/06/19 14:30:41 [netclient] starting wireguard
<a id="__codelineno-7-7" name="__codelineno-7-7"></a><a href="#__codelineno-7-7"><span class="linenos" data-linenos=" 7 "></span></a>2022/06/19 14:30:41 [netclient] writing wg conf file to: C:\ProgramData\Netclient\nm-sc-devvpn.conf
<a id="__codelineno-7-8" name="__codelineno-7-8"></a><a href="#__codelineno-7-8"><span class="linenos" data-linenos=" 8 "></span></a>2022/06/19 14:30:41 [netclient] waiting for interface...
<a id="__codelineno-7-9" name="__codelineno-7-9"></a><a href="#__codelineno-7-9"><span class="linenos" data-linenos=" 9 "></span></a>2022/06/19 14:30:51 [netclient] error installing: could not create wg interface for nm-sc-devvpn
<a id="__codelineno-7-10" name="__codelineno-7-10"></a><a href="#__codelineno-7-10"><span class="linenos" data-linenos="10 "></span></a>2022/06/19 14:30:51 [netclient] removed machine from sc-devvpn network on remote server
<a id="__codelineno-7-11" name="__codelineno-7-11"></a><a href="#__codelineno-7-11"><span class="linenos" data-linenos="11 "></span></a>2022/06/19 14:30:51 error running command: wireguard.exe /uninstalltunnelservice nm-sc-devvpn
<a id="__codelineno-7-12" name="__codelineno-7-12"></a><a href="#__codelineno-7-12"><span class="linenos" data-linenos="12 "></span></a>2022/06/19 14:30:51
<a id="__codelineno-7-13" name="__codelineno-7-13"></a><a href="#__codelineno-7-13"><span class="linenos" data-linenos="13 "></span></a>2022/06/19 14:30:51 [netclient] unable to wipe local config
<a id="__codelineno-7-14" name="__codelineno-7-14"></a><a href="#__codelineno-7-14"><span class="linenos" data-linenos="14 "></span></a>2022/06/19 14:30:51 [netclient] used backup file for network: sc-devvpn
<a id="__codelineno-7-15" name="__codelineno-7-15"></a><a href="#__codelineno-7-15"><span class="linenos" data-linenos="15 "></span></a>2022/06/19 14:30:51 [netclient] error removing artifacts: open C:\ProgramData\Netclient\netconfig-sc-devvpn: The system cannot find the file specified.
<a id="__codelineno-7-16" name="__codelineno-7-16"></a><a href="#__codelineno-7-16"><span class="linenos" data-linenos="16 "></span></a>2022/06/19 14:30:51 [netclient] error removing services: open C:\ProgramData\Netclient\netconfig-sc-devvpn: The system cannot find the file specified.
<a id="__codelineno-7-17" name="__codelineno-7-17"></a><a href="#__codelineno-7-17"><span class="linenos" data-linenos="17 "></span></a>2022/06/19 14:30:51 open C:\ProgramData\Netclient\netconfig-sc-devvpn: The system cannot find the file specified.
<a id="__codelineno-7-18" name="__codelineno-7-18"></a><a href="#__codelineno-7-18"><span class="linenos" data-linenos="18 "></span></a>PS D:\download&gt;
</code></pre></div>
<div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1"></a><a href="#__codelineno-8-1"><span class="linenos" data-linenos=" 1 "></span></a>D:\download&gt; .\netclient.exe join -t xxxxxxxxxxxx
<a id="__codelineno-8-2" name="__codelineno-8-2"></a><a href="#__codelineno-8-2"><span class="linenos" data-linenos=" 2 "></span></a>2022/06/19 14:26:19 Gravitl Netclient on Windows started
<a id="__codelineno-8-3" name="__codelineno-8-3"></a><a href="#__codelineno-8-3"><span class="linenos" data-linenos=" 3 "></span></a>2022/06/19 14:26:19 [netclient] joining sc-devvpn at 120.xx.xx.xx:50056
<a id="__codelineno-8-4" name="__codelineno-8-4"></a><a href="#__codelineno-8-4"><span class="linenos" data-linenos=" 4 "></span></a>2022/06/19 14:26:20 [netclient] node created on remote server...updating configs
<a id="__codelineno-8-5" name="__codelineno-8-5"></a><a href="#__codelineno-8-5"><span class="linenos" data-linenos=" 5 "></span></a>2022/06/19 14:26:20 [netclient] retrieving peers
<a id="__codelineno-8-6" name="__codelineno-8-6"></a><a href="#__codelineno-8-6"><span class="linenos" data-linenos=" 6 "></span></a>2022/06/19 14:26:20 [netclient] starting wireguard
<a id="__codelineno-8-7" name="__codelineno-8-7"></a><a href="#__codelineno-8-7"><span class="linenos" data-linenos=" 7 "></span></a>2022/06/19 14:26:20 [netclient] writing wg conf file to: C:\ProgramData\Netclient\nm-sc-devvpn.conf
<a id="__codelineno-8-8" name="__codelineno-8-8"></a><a href="#__codelineno-8-8"><span class="linenos" data-linenos=" 8 "></span></a>2022/06/19 14:26:20 [netclient] error writing wg conf file to C:\Program Files\WireGuard\Data\Configurations\nm-sc-devvpn.conf: open C:\Program Files\WireGuard\Data\Configurations\nm-sc-devvpn.conf: The system cannot find the path specified.
<a id="__codelineno-8-9" name="__codelineno-8-9"></a><a href="#__codelineno-8-9"><span class="linenos" data-linenos=" 9 "></span></a>2022/06/19 14:26:20 [netclient] error installing: open C:\Program Files\WireGuard\Data\Configurations\nm-sc-devvpn.conf: The system cannot find the path specified.
<a id="__codelineno-8-10" name="__codelineno-8-10"></a><a href="#__codelineno-8-10"><span class="linenos" data-linenos="10 "></span></a>2022/06/19 14:26:20 [netclient] removed machine from sc-devvpn network on remote server
<a id="__codelineno-8-11" name="__codelineno-8-11"></a><a href="#__codelineno-8-11"><span class="linenos" data-linenos="11 "></span></a>2022/06/19 14:26:20 error running command: wireguard.exe /uninstalltunnelservice nm-sc-devvpn
<a id="__codelineno-8-12" name="__codelineno-8-12"></a><a href="#__codelineno-8-12"><span class="linenos" data-linenos="12 "></span></a>2022/06/19 14:26:20
<a id="__codelineno-8-13" name="__codelineno-8-13"></a><a href="#__codelineno-8-13"><span class="linenos" data-linenos="13 "></span></a>2022/06/19 14:26:20 [netclient] unable to wipe local config
<a id="__codelineno-8-14" name="__codelineno-8-14"></a><a href="#__codelineno-8-14"><span class="linenos" data-linenos="14 "></span></a>2022/06/19 14:26:20 [netclient] used backup file for network: sc-devvpn
<a id="__codelineno-8-15" name="__codelineno-8-15"></a><a href="#__codelineno-8-15"><span class="linenos" data-linenos="15 "></span></a>2022/06/19 14:26:20 [netclient] error removing artifacts: open C:\ProgramData\Netclient\netconfig-sc-devvpn: The system cannot find the file specified.
<a id="__codelineno-8-16" name="__codelineno-8-16"></a><a href="#__codelineno-8-16"><span class="linenos" data-linenos="16 "></span></a>2022/06/19 14:26:20 [netclient] error removing services: open C:\ProgramData\Netclient\netcon
</code></pre></div>
<ul>
<li>
<p>windows下netclient join会依赖 C:\Program Files\WireGuard\wg.exe 和 C:\Program Files\WireGuard\wireguard.exe
源码分析：https://github1s.com/gravitl/netmaker/blob/master/netclient/ncutils/netclientutils.go#L49-L50</p>
</li>
<li>
<p>但亲测发现，虽然会调用 wg.exe和wireguard.exe，但是不能且不需要显示启动 wireguard.exe，否则会产生冲突，且会执行 wireguard.exe /installtunnelservice "%s" 命令安装wireguard为系统服务，参考源码：
https://github1s.com/gravitl/netmaker/blob/master/netclient/wireguard/windows.go#L13-L14</p>
</li>
<li>
<p><strong><em>总结：</em></strong> 通常应该安装 wireguard-amd64-0.5.3.msi 和 netclient.exe组合使用，本质上是 netclient.exe命令行调用 wireguard.exe等，但切记不可同时启动否则会冲突导致无法全连接到peers。（netclient的作用是可以动态发现，反之如果仅配置wireguard.exe则不能动态发现每个 peers 的 NAT 映射端口配置信息。</p>
</li>
</ul>
<blockquote>
<p>如果使用 wireguard-amd64.msi 和 netclient.exe，则无需安装 TunSafe-Tap，另外关于使用 TunSafe作为Windows客户端的方案，目前未找到修改连接到 TunSafe server 的入口，因为墙内连接不上，因此不考虑。</p>
</blockquote>
<ul>
<li>如果提升 joined 成功了，但依然连接不上，可尝试重新执行多尝试几次即可</li>
</ul>
<div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1"></a><a href="#__codelineno-9-1"><span class="linenos" data-linenos="1 "></span></a>## 1.先停止 peers 连接
<a id="__codelineno-9-2" name="__codelineno-9-2"></a><a href="#__codelineno-9-2"><span class="linenos" data-linenos="2 "></span></a>./netclient.exe leave -n sc-devvpn
<a id="__codelineno-9-3" name="__codelineno-9-3"></a><a href="#__codelineno-9-3"><span class="linenos" data-linenos="3 "></span></a>
<a id="__codelineno-9-4" name="__codelineno-9-4"></a><a href="#__codelineno-9-4"><span class="linenos" data-linenos="4 "></span></a>## 2.卸载 netclient
<a id="__codelineno-9-5" name="__codelineno-9-5"></a><a href="#__codelineno-9-5"><span class="linenos" data-linenos="5 "></span></a>./netclient.exe uninstall
<a id="__codelineno-9-6" name="__codelineno-9-6"></a><a href="#__codelineno-9-6"><span class="linenos" data-linenos="6 "></span></a>
<a id="__codelineno-9-7" name="__codelineno-9-7"></a><a href="#__codelineno-9-7"><span class="linenos" data-linenos="7 "></span></a>## 3.重新加入 peers 组
<a id="__codelineno-9-8" name="__codelineno-9-8"></a><a href="#__codelineno-9-8"><span class="linenos" data-linenos="8 "></span></a>./netclient.exe join -t xxxxxx
</code></pre></div>

              
            </article>
          </div>
        </div>
        
      </main>
      
        <footer class="md-footer">
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-copyright">
  
  
    Made with
    <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
      Material for MkDocs
    </a>
  
</div>
      
    </div>
  </div>
</footer>
      
    </div>
    <div class="md-dialog" data-md-component="dialog">
      <div class="md-dialog__inner md-typeset"></div>
    </div>
    <script id="__config" type="application/json">{"base": "../../../..", "features": ["search.suggest", "search.highlight", "navigation.tabs", "navigation.expand", "toc.follow", "toc.integrate"], "search": "../../../../assets/javascripts/workers/search.5e67fbfe.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version.title": "Select version"}, "version": {"default": "latest", "provider": "mike"}}</script>
    
    
      <script src="../../../../assets/javascripts/bundle.c44cc438.min.js"></script>
      
        <script src="../../../../static/js/util.js"></script>
      
    
  </body>
</html>